import { Button, Card, Checkbox, Form, Popover, Space } from 'antd';
import { min_app_fs, min_app_shell } from '@linksaas-minapp/api';
import toml from "@iarna/toml";
import { useState } from 'react';
import type { ReviveConfig } from '@/components/revive';
import useForceUpdate from 'use-force-update';
import { ReviveRuleKeyList, setArguments, setRuleDisabled } from "@/components/revive";
import ReviveItem from "@/components/ReviveItem";
import SelectRuleModal from '@/components/SelectRuleModal';
import { QuestionCircleOutlined } from "@ant-design/icons";

export default function Home() {
  const forceUpdate = useForceUpdate();

  const [lintCfg, setLintCfg] = useState<ReviveConfig>({ ignoreGeneratedHeader: true, rule: {} });
  const [showRuleModal, setShowRuleModal] = useState(false);

  const openFile = async () => {
    let files = await min_app_fs.readFile(
      false,
      "toml文件", ["toml"]
    );
    if (files.length == 0) {
      return;
    }
    try {
      const content = new TextDecoder("utf-8").decode(files[0].file_data);
      const cfg = toml.parse(content) as unknown as ReviveConfig;
      setLintCfg(cfg);
    } catch (e) {
      console.log(e);
    }
  };

  const saveFile = async () => {
    const tmpCfg = lintCfg;
    if (tmpCfg.enableAllRules !== true) {
      //清除disable配置
      ReviveRuleKeyList.forEach(ruleKey => {
        if (tmpCfg.rule[ruleKey] !== undefined) {
          delete tmpCfg.rule[ruleKey]!.Disabled;
          delete tmpCfg.rule[ruleKey]!.disabled;
        }
      });
    }
    const content = toml.stringify(tmpCfg as unknown as toml.JsonMap);
    const data = new TextEncoder().encode(content);
    await min_app_fs.writeFile("config.toml", data);
  }

  return (
    <Card title={
      <Popover placement='right' trigger='hover' content={
        <div>
          <p>Fast, configurable, extensible, flexible, and beautiful linter for Go. Drop-in replacement of golint. Revive provides a framework for development of custom rules, and lets you define a strict preset for enhancing your development & code review processes.</p>
          <p>Here is how revive is different from golint:</p>
          <ul>
            <li>Allows to enable or disable rules using a configuration file.</li>
            <li>Allows to configure the linting rules with a TOML file.</li>
            <li>2x faster running the same rules as golint.</li>
            <li>Provides functionality for disabling a specific rule or the entire linter for a file or a range of lines.</li>
            <li>golint allows this only for generated files.</li>
            <li>Optional type checking. Most rules in golint do not require type checking. If you disable them in the config file, revive will run over 6x faster than golint.</li>
            <li>Provides multiple formatters which let us customize the output.</li>
            <li>Allows to customize the return code for the entire linter or based on the failure of only some rules.</li>
            <li>Everyone can extend it easily with custom rules or formatters.</li>
            <li>Revive provides more rules compared to golint.</li>
          </ul>
        </div>
      }>
        <span>revive配置助手&nbsp;<QuestionCircleOutlined /></span>
      </Popover>} bordered={false} extra={
        <Space>
          <Button type="link" onClick={e => {
            e.stopPropagation();
            e.preventDefault();
            min_app_shell.openBrowser("https://revive.run/");
          }}>官方网站</Button>
          <Button onClick={e => {
            e.stopPropagation();
            e.preventDefault();
            setLintCfg({ ignoreGeneratedHeader: true, rule: {} });
          }}>清空配置</Button>
          <Button onClick={e => {
            e.stopPropagation();
            e.preventDefault();
            openFile();
          }}>导入</Button>
          <Button onClick={e => {
            e.stopPropagation();
            e.preventDefault();
            saveFile();
          }}>导出</Button>
        </Space>
      }>
      <Form labelCol={{ span: 6 }}>
        <Form.Item label="忽略包含GENERATED的文件">
          <Checkbox checked={lintCfg.ignoreGeneratedHeader ?? true} onChange={e => {
            e.stopPropagation();
            setLintCfg({ ...lintCfg, ignoreGeneratedHeader: e.target.checked });
          }} />
        </Form.Item>
        <Form.Item label="使用所有检查规则">
          <Checkbox checked={lintCfg.enableAllRules ?? false} onChange={e => {
            e.stopPropagation();
            setLintCfg({ ...lintCfg, enableAllRules: e.target.checked });
          }} />
        </Form.Item>
      </Form>
      <Card bordered={false} title="规则列表" extra={
        <Button type='primary' onClick={e => {
          e.stopPropagation();
          e.preventDefault();
          setShowRuleModal(true);
        }}>增加规则</Button>
      }>
        {ReviveRuleKeyList.filter(ruleKey => lintCfg.rule[ruleKey] != undefined).map(ruleKey => (
          <ReviveItem key={ruleKey} ruleKey={ruleKey} enableAll={lintCfg.enableAllRules ?? false} reviveRule={lintCfg.rule[ruleKey]!}
            onRemove={() => {
              setLintCfg(oldValue => {
                delete oldValue.rule[ruleKey];
                return oldValue;
              });
              forceUpdate();
            }}
            onDisable={(newVal) => {
              setLintCfg(oldValue => {
                setRuleDisabled(oldValue.rule[ruleKey]!, newVal);
                return oldValue;
              });
              forceUpdate();
            }}
            onChange={(newArgs) => {
              setLintCfg(oldValue => {
                setArguments(oldValue.rule[ruleKey]!, newArgs);
                return oldValue;
              });
              forceUpdate();
            }} />
        ))}
      </Card>
      {showRuleModal == true && (
        <SelectRuleModal curRuleList={Object.keys(lintCfg.rule)} onCancel={() => setShowRuleModal(false)} onSelect={(rule) => {
          setLintCfg(oldValue => {
            oldValue.rule[rule.id] = {};
            if (rule.demoValue != undefined) {
              setArguments(oldValue.rule[rule.id]!, rule.demoValue);
            }
            return oldValue;
          });
          setShowRuleModal(false);
          forceUpdate();
        }} />
      )}
    </Card>
  );
}
